#! /usr/bin/python3
# -*- coding: UTF-8 -*-
  
'''※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
File Name: get_area_code.py
Author: GID5564
Description: 获取行政区域编码
Version: 1.0
Created Time: 12/06/24-21:01:59
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※'''

import requests
from bs4 import BeautifulSoup
import csv
import os
from concurrent.futures import ThreadPoolExecutor

from todb import newDB,insertDB

def save_to_csv(data, file_name):
    with open(f'/home/save/{file_name}.csv', 'w', newline='', encoding='utf-8') as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow(['name', 'code'])
        for item in data:
            writer.writerow(item)

def write_string_to_file(file_path: str, content: str) -> None:
    """
    将字符串写入文本文件

    :param file_path: 文件路径，类型为str
    :param content: 要写入的字符串内容，类型为str
    :return: 无返回值
    """
    with open(file_path, 'a', encoding='utf-8') as f:
        f.write(content)

def debug(content: str) -> None:
    """
    将字符串写入文本文件

    :param file_path: 文件路径，类型为str
    :param content: 要写入的字符串内容，类型为str
    :return: 无返回值
    """
    file_path="error.txt"
    with open(file_path, 'a', encoding='utf-8') as f:
        f.write(content)


class CityCode_CN():
    def __init__(self,year):
        self.base_url='https://www.stats.gov.cn/sj/tjbz/tjyqhdmhcxhfdm'
        self.year=year
    
    def get_province_url(self):
        """
        获取省名及其下级url的列表： 
        [(name,url),(name,url),(name,url),…]，url中含编码
        """
        #url='https://www.stats.gov.cn/sj/tjbz/tjyqhdmhcxhfdm/2023/index.html'

        url = f"{self.base_url}/{self.year}/index.html"
        try:
            response = requests.get(url)
            response.encoding = 'utf-8'
            soup = BeautifulSoup(response.text, 'html.parser')
            province_list = soup.find_all('tr', {'class': 'provincetr'})
        except (requests.ConnectionError, requests.Timeout) as e:
            print(f"发生错误: {e}")
            #--------------------
            msg=f"E: {e},FUNC: provice,URL: {url}"
            debug(msg)
            #--------------------
            return []

        province_urls = [(pro.get_text(), pro['href']) for province in province_list for pro in province.find_all('a')]
        
        #print(province_urls)
        return province_urls

    def get_city_url(self, province_url):
        """
        获取区市下级url的列表： 
        [(name, code, url), (name, code, url), (name, code, url), …]
        """
        if not province_url:
            return None
        #url='https://www.stats.gov.cn/sj/tjbz/tjyqhdmhcxhfdm/2023/11.html'
        #url="https://www.stats.gov.cn/sj/tjbz/tjyqhdmhcxhfdm/2023/50.html"
        url = f"{self.base_url}/{self.year}/{province_url}"
        try:
            response = requests.get(url)
            response.encoding = 'utf-8'
            soup = BeautifulSoup(response.text, 'html.parser')
            city_list = soup.find_all('tr', {'class': ['citytr']})
        except (requests.ConnectionError, requests.Timeout) as e:
            print(f"发生错误: {e}")
            #--------------------
            msg=f"E: {e},FUNC: city,URL: {url}"
            debug(msg)
            #--------------------
            return []
        
        city_url = []
        city_code = []
        city_name = []
        
        
        for city in city_list:
            a_tags = city.find_all('a')
            for tag in a_tags:
                if 'href' in tag.attrs:
                    temp=tag['href']
                    if temp not in city_url:
                        city_url.append(temp)
                else:
                    if "" not in city_url:
                        city_url.append("")

                text=tag.get_text()
                if text.isdigit():
                    city_code.append(text)
                else:
                    city_name.append(text)
        
            
        city_info = [(name, code, url) for name, code, url in zip(city_name, city_code, city_url)]

        #print(city_info)
        return city_info

    def get_county_url(self, city_url):
        """
        获取区县名、区代码及其下级url的列表： 
        [(name, code, url), (name, code, url), (name, code, url), …]
        """
        if not city_url:
            return None
        #url = f"https://www.stats.gov.cn/sj/tjbz/tjyqhdmhcxhfdm/2023/34.html"

        url = f"{self.base_url}/{self.year}/{city_url}"
        try:
            response = requests.get(url)
            response.encoding = 'utf-8'
            soup = BeautifulSoup(response.text, 'html.parser')
            county_list = soup.find_all('tr', {'class': ['countytr']})
        except (requests.ConnectionError, requests.Timeout) as e:
            print(f"发生错误: {e}")
            #--------------------
            msg=f"E: {e},FUNC: county,URL: {url}"
            debug(msg)
            #--------------------
            return []
            
        county_info = []
        for county in county_list:
            a_urls = county.find_all('a')
            county_name = [a_url.get_text() for a_url in a_urls if not a_url.get_text().isdigit()]
            county_code = [a_url.get_text() for a_url in a_urls if a_url.get_text().isdigit()]
            county_url = list(set([a_url['href'] for a_url in a_urls]))

            county_info.extend(zip(county_name, county_code, county_url))

        #print(county_info)
        return county_info

    def get_town_url(self, county_url):
        """
        获取乡镇街道名、区代码及其下级url的列表： 
        [(name, code, url), (name, code, url), (name, code, url), …]
        """
        if not county_url:
            return None
        #url = f"https://www.stats.gov.cn/sj/tjbz/tjyqhdmhcxhfdm/2023/34/08/340826.html"

        url = f"{self.base_url}/{self.year}/{county_url}"
        try:
            response = requests.get(url)
            response.encoding = 'utf-8'
            soup = BeautifulSoup(response.text, 'html.parser')
            town_list = soup.find_all('tr', {'class': ['towntr']})
        except (requests.ConnectionError, requests.Timeout) as e:
            print(f"发生错误: {e}")
            #--------------------
            msg=f"E: {e},FUNC: town,URL: {url}"
            debug(msg)
            #--------------------
            return []

        town_info = []
        town_names = []
        town_codes = []
        unique_urls = set() #存储不重复的url

        for town in town_list:
            a_tags = town.find_all('a')
            for a_tag in a_tags:
                href = a_tag['href']
                if href not in unique_urls:
                    unique_urls.add(href)
                text = a_tag.get_text()
                if text.isdigit():
                    town_codes.append(text)
                else:
                    town_names.append(text)

        town_info = [(name, code, url) for name, code, url in zip(town_names, town_codes, unique_urls)]
        #print(town_info)
        return town_info

        
    def get_village_code(self, town_url):
        """
        获取村委会、区代码列表： 
        [(name, code, level), (name, code, level), (name, code, level), …]
        """
        if not town_url:
            return None
        #url = f"https://www.stats.gov.cn/sj/tjbz/tjyqhdmhcxhfdm/2023/34/08/26/340826103.html"

        url = f"{self.base_url}/{self.year}/{town_url}"
        try:
            response = requests.get(url)
            response.encoding = 'utf-8'
            soup = BeautifulSoup(response.text, 'html.parser')
            village_list = soup.find_all('tr', {'class': ['villagetr']})
        except (requests.ConnectionError, requests.Timeout) as e:
            print(f"发生错误: {e}")
            #--------------------
            msg=f"E: {e},FUNC: village,URL: {url}"
            debug(msg)
            #--------------------
            return []
            
        village_info = [(a_urls[2].get_text(), a_urls[0].get_text(), a_urls[1].get_text()) for village in village_list for a_urls in [village.find_all('td')]]
        
        #print(village_info)
        return village_info


def get_code(year):
    # 获取城市代码对象
    cc = CityCode_CN(year)
    # 获取省份URL列表
    provinces = cc.get_province_url()

    # 处理省份信息
    def process_province(pro):
        province_info,city_info,county_info,town_info,village_info = [], [], [], [], []

        province_name, province_code = pro
        province_info.append((province_name, province_code.split('.')[0]))
        
        #print(f"获取{province_name}信息中……")
        # 获取城市URL列表
        citys = cc.get_city_url(province_code)
        if citys is None:
            return [], [], [], [], []
        # 提取城市名称和城市代码
        for city_name,city_code,city_url in citys:
            if city_name == '市辖区':
                city_name = province_name
            city_info.append((city_name, city_code[:4]))

            
            # 获取区县URL列表
            countys = cc.get_county_url(city_url)
            if countys is None:
                continue
            
            
            # 遍历区县信息
            for county_name, county_code,county_url in countys:
                county_info.append((county_name, county_code[:6]))
                
                
                # 获取乡镇URL列表
                new_county_url=f"{county_code[:2]}/{county_url}"
                towns = cc.get_town_url(new_county_url)

                # 遍历乡镇信息
                for town_name, town_code,town_url in towns:
                    town_info.append((town_name, town_code[:9]))
                
                    # 获取村庄URL列表
                    new_town_url=f"{town_code[:2]}/{town_code[2:4]}/{town_url}"
                    villages = cc.get_village_code(new_town_url)

                    # 遍历村庄信息
                    for village_name, village_code,village_level in villages:
                        village_info.append((village_name, village_code[:12]))
                    
                    write_string_to_file("infomation.txt",f"{province_name} - {city_name} - {county_name} - {town_name}")
                    
                    print(f"已获取 {province_name} - {city_name} - {county_name} - {town_name} ")
                
        return province_info, city_info, county_info,town_info,village_info
    # 使用线程池并发处理省份信息
    with ThreadPoolExecutor() as executor:
        results = list(executor.map(process_province, provinces))
    # 将结果拆分为省份、城市、区县、乡镇、村庄信息
    province_info, city_info, county_info,town_info,village_info = zip(*results)
    # 将嵌套的列表展平
    province_info = [item for sublist in province_info for item in sublist]
    city_info = [item for sublist in city_info for item in sublist]
    county_info = [item for sublist in county_info for item in sublist]
    town_info = [item for sublist in town_info for item in sublist]
    village_info = [item for sublist in village_info for item in sublist]

    # 将结果保存到CSV文件
    save_to_csv(province_info, 'province')
    save_to_csv(city_info, 'city')
    save_to_csv(county_info, 'county')
    save_to_csv(town_info, 'town')
    save_to_csv(village_info, 'village')


def get_zone_code(year,level):
    # 获取城市代码对象
    cc = CityCode_CN(year)
    # 获取省份URL列表
    provinces = cc.get_province_url()
    # 处理省份信息
    def process_province(pro):
        province_info,city_info,county_info,town_info,village_info = [], [], [], [], []
        
        #省区划代码
        province_name, province_code = pro
        province_info.append((province_name, province_code.split('.')[0]))
        
        #市区划代码
        citys = cc.get_city_url(province_code)
        if citys is None:
            return [], [], [], [], []
        # 提取城市名称和城市代码
        for city_name,city_code,city_url in citys:
            if city_name == '市辖区':
                city_name = province_name
            city_info.append((city_name, city_code[:4]))
            
            #县区划代码
            countys = cc.get_county_url(city_url)
            if countys is None:
                continue
            # 遍历区县信息
            for county_name, county_code,county_url in countys:
                county_info.append((county_name, county_code[:6]))
                
                #乡区划代码
                new_county_url=f"{county_code[:2]}/{county_url}"
                towns = cc.get_town_url(new_county_url)
                # 遍历乡镇信息
                for town_name, town_code,town_url in towns:
                    town_info.append((town_name, town_code[:9]))
                    print(f"已获取 {province_name} - {city_name} - {county_name} - {town_name} ")

        return province_info, city_info, county_info,town_info

    # 使用线程池并发处理省份信息
    with ThreadPoolExecutor() as executor:
        results = list(executor.map(process_province, provinces))

    
    # 将结果拆分为省份、城市、区县、乡镇、村庄信息
    province_info, city_info, county_info,town_info = zip(*results)
    # 将嵌套的列表展平
    province_info = [item for sublist in province_info for item in sublist]
    city_info = [item for sublist in city_info for item in sublist]
    county_info = [item for sublist in county_info for item in sublist]
    town_info = [item for sublist in town_info for item in sublist]

    # 将结果保存到CSV文件
    save_to_csv(province_info, 'province')
    save_to_csv(city_info, 'city')
    save_to_csv(county_info, 'county')
    save_to_csv(town_info, 'town')



if __name__ == '__main__':
    #cc=CityCode_CN('2023')
    #cc.get_province_url()
    #cc.get_city_url('13.html')
    #cc.get_county_url('44/4403.html')
    #cc.get_town_url('34/08/340826.html')
    #cc.get_village_code('34/08/26/340826103.html')

    
    #https://www.stats.gov.cn/sj/tjbz/tjyqhdmhcxhfdm/2023/34/08/26/340826103.html
    #get_code(2023)
    get_zone_code(2023,0)




















